package ModelAndController;

import java.io.*;
import java.util.*;

//Exception 200 es 239 kozott
public class ReadCircuitFromFile {
	
	private String[] fileContent;
	private int[] elementPozitionsInFile;
	
	private Gate[] inputGate;
	private int saveInputGatePozition;
	private Gate[] outputGate;
	private int saveOutputGatePozition;
	
	private SignalGenerator[] signalGenerators;
	private int saveSignalGeneratorsPozition;
	private Switch[] switches;
	private int saveSwitchesPozition;
	
	private Composite[] composites;
	private int saveCompositePozition;
	
	private Display[] display;
	private int saveDisplayPozition;
	
	private Scope[] scope;
	private int saveScopePozition;
	
	private Element[] elements;
	private Wire[] wires;
	private int saveWires;
	private int[] saveWiresOnActualElement;
	
	private int nbOfMaxUpdates;

	private int nbOfCircuitElements;
	
	public ReadCircuitFromFile(int copyOfNbOfCircuitElements){
		nbOfCircuitElements = copyOfNbOfCircuitElements;
	}
	
	public CircuitElements readInCircuit(String fileName, int copyNbOfMaxUpdates) throws Exception{
		nbOfMaxUpdates = copyNbOfMaxUpdates;
		
		File file= new File(fileName);
		if(!file.exists())
			throw new Exception("200 "+fileName);
		fillFileContent(file);
		
		CircuitElements retCircuit = null;
		try{
			retCircuit = createCircuitElementsFromFile();
			if( nbOfCircuitElements == 0)
				retCircuit.checkCircuitElements();
		}catch(Exception e){
			throw new Exception(e.getMessage()+" in File: "+fileName);
		}
		
		return retCircuit;
	}
	
	//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*
	//fillFileContent
	
	private void fillFileContent(File file) throws Exception{
		countValideLinesAndInitFileContent(file);
		actualFillFileContent(file);
	}
	
	private void actualFillFileContent(File file) throws Exception{
		int actNbOfLine = 0;
		try{
			String line;
			Scanner reader = new Scanner(file);
			while( reader.hasNextLine() ){
				line = reader.nextLine();
				StringTokenizer tks = new StringTokenizer(line);
				String firstToken = tks.nextToken();
				if( firstToken.contentEquals("-") || firstToken.contentEquals("#")){
					fileContent[actNbOfLine] = line;
					actNbOfLine++;
				}
			}
		}catch(Exception e){
			throw new Exception("203");
		}
	}
	
	private void countValideLinesAndInitFileContent(File file) throws Exception{
		int nbOfLines = 0;
		try{
			String line;
			Scanner reader = new Scanner(file);
			while(reader.hasNextLine()){
				line = reader.nextLine();
				StringTokenizer tks = new StringTokenizer(line);
				String firstToken = tks.nextToken();
				if( firstToken.contentEquals("-") || firstToken.contentEquals("#"))
					nbOfLines++;
			}
		}catch(Exception e){
			throw new Exception("201");
		}
		if(nbOfLines == 0)
			throw new Exception("202");
		fileContent = new String[nbOfLines];
	}
	
	//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*
	//createCircuitElementsFromFile()
	
	private CircuitElements createCircuitElementsFromFile() throws Exception{
		createElements();
		createWires();
		CircuitElements circuitElements = new CircuitElements(nbOfCircuitElements, inputGate, outputGate, signalGenerators, switches, composites, display, scope, elements, wires);
		return circuitElements;
	}
	
	//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*
	//createElements()
	
	private void createElements() throws Exception{	
		initAndFillElementPozitionsInFile();
		testElementSerialNb();
		initArraysOfCircuitElements();
		fillElementsArray();
	}
	
	private void testElementSerialNb() throws Exception{
		int[] serialNbOfElements = new int[elementPozitionsInFile.length];
		for(int act=0; act<serialNbOfElements.length; act++)
			serialNbOfElements[act] = act;
		
		int pozOfNb = 0;
		for(int act=0; act<elementPozitionsInFile.length; act++){
			StringTokenizer tks = new StringTokenizer(fileContent[elementPozitionsInFile[act]]);
			tks.nextToken();
			int actSerialNb;
			try{
				actSerialNb = Integer.parseInt( tks.nextToken() );
			}catch(Exception e){
				throw new Exception("204 "+fileContent[ elementPozitionsInFile[act] ]);
			}
			if(actSerialNb != serialNbOfElements[pozOfNb])
				throw new Exception("205 "+fileContent[ elementPozitionsInFile[act] ]);
			pozOfNb++;
		}
	}
	
	private void initAndFillElementPozitionsInFile() throws Exception{
		int nbOfElements = countElementsInFile();
		if( nbOfElements < 1)
			throw new Exception("206");
		elementPozitionsInFile = new int[nbOfElements];
		fillElementPozitionsInFile();
	}
	
	private int countElementsInFile(){
		int retValue = 0;
		for(int act=0; act<fileContent.length; act++){
			StringTokenizer tks = new StringTokenizer(fileContent[act]);
			String first = tks.nextToken();
			if(first.contentEquals("#"))
				retValue++;
		}
		return retValue;
	}
	
	private void fillElementPozitionsInFile(){
		int save = 0;
		for(int act=0; act<fileContent.length; act++){
			StringTokenizer tks = new StringTokenizer(fileContent[act]);
			String first = tks.nextToken();
			if(first.contentEquals("#")){
				elementPozitionsInFile[save] = act;
				save++;
			}
		}
	}
	
	//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*
	//initArraysOfCircuitElements()
	
	private void initArraysOfCircuitElements() throws Exception{
		initInputGateArray();
		initOutputGateArray();
		initSignalGeneratorArray();
		initSwichArray();
		initCompositeArray();
		initDisplayArray();
		initScopeArray();
		initElementsArray();
	}
	
	private void initInputGateArray(){
		int nbOfInputGate = countInputGateNb();
		if( 0 < nbOfInputGate ){
			inputGate = new Gate[nbOfInputGate];
			saveInputGatePozition = 0;
		}
	}
	
	private int countInputGateNb(){
		int retValue = 0;
		
		for(int act=0; act<elementPozitionsInFile.length; act++){
			StringTokenizer tks = new StringTokenizer(fileContent[elementPozitionsInFile[act]]);
			tks.nextToken();
			tks.nextToken();
			String type = tks.nextToken();
			String inputOrOutput = tks.nextToken();
			if(type.toLowerCase().contentEquals("gate") && inputOrOutput.toLowerCase().contentEquals("input"))
				retValue++;
		}
		
		return retValue;
	}
	
	private void initOutputGateArray(){
		int nbOfOutputGate = countOutputGateNb();
		if( 0 < nbOfOutputGate ){
			outputGate = new Gate[nbOfOutputGate];
			saveOutputGatePozition = 0;
		}
	}
	
	private int countOutputGateNb(){
		int retValue = 0;
		
		for(int act=0; act<elementPozitionsInFile.length; act++){
			StringTokenizer tks = new StringTokenizer(fileContent[elementPozitionsInFile[act]]);
			tks.nextToken();
			tks.nextToken();
			String type = tks.nextToken();
			String inputOrOutput = tks.nextToken();
			if(type.toLowerCase().contentEquals("gate") && inputOrOutput.toLowerCase().contentEquals("output"))
				retValue++;
		}
		
		return retValue;
	}
	
	private void initSignalGeneratorArray(){
		int nbOfSignalGenerator = countSignalGeneratorNb();
		if( 0 < nbOfSignalGenerator){
			signalGenerators = new SignalGenerator[nbOfSignalGenerator];
			saveSignalGeneratorsPozition = 0;
		}
	}
	
	private int countSignalGeneratorNb(){
		int retValue = 0;
		
		for(int act=0; act<elementPozitionsInFile.length; act++){
			StringTokenizer tks = new StringTokenizer(fileContent[elementPozitionsInFile[act]]);
			tks.nextToken();
			tks.nextToken();
			String type = tks.nextToken();
			if(type.toLowerCase().contentEquals("signalgenerator"))
				retValue++;
		}
		
		return retValue;
	}
	
	private void initSwichArray(){
		int nbOfSwitch = countSwitchNb();
		if( 0 < nbOfSwitch){
			switches = new Switch[nbOfSwitch];
			saveSwitchesPozition = 0;
		}
	}
	
	private void initCompositeArray(){
		int nbOfComposite = countCompositeNb();
		if( 0 < nbOfComposite){
			composites = new Composite[nbOfComposite];
			saveCompositePozition = 0;
		}
	}
	
	private int countSwitchNb(){
		int retValue = 0;
		
		for(int act=0; act<elementPozitionsInFile.length; act++){
			StringTokenizer tks = new StringTokenizer(fileContent[elementPozitionsInFile[act]]);
			tks.nextToken();
			tks.nextToken();
			String type = tks.nextToken();
			if(type.toLowerCase().contentEquals("switch"))
				retValue++;
		}
		
		return retValue;
	}
	
	private int countCompositeNb(){
		int retValue = 0;
		
		for(int act=0; act<elementPozitionsInFile.length; act++){
			StringTokenizer tks = new StringTokenizer(fileContent[elementPozitionsInFile[act]]);
			tks.nextToken();
			tks.nextToken();
			String type = tks.nextToken();
			if(type.toLowerCase().contentEquals("composite"))
				retValue++;
		}
		
		return retValue;
	}
	
	private void initDisplayArray(){
		int nbOfDisplay = countDisplayNb();
		if( 0 < nbOfDisplay){
			display = new Display[nbOfDisplay];
			saveDisplayPozition = 0;
		}
	}
	
	private int countDisplayNb(){
		int retValue = 0;
		
		for(int act=0; act<elementPozitionsInFile.length; act++){
			StringTokenizer tks = new StringTokenizer(fileContent[elementPozitionsInFile[act]]);
			tks.nextToken();
			tks.nextToken();
			String type = tks.nextToken();
			if(type.toLowerCase().contentEquals("display"))
				retValue++;
		}
		
		return retValue;
	}
	
	private void initScopeArray(){
		int nbOfScope = countScopeNb();
		if( 0 < nbOfScope){
			scope = new Scope[nbOfScope];
			saveScopePozition = 0;
		}
	}
	
	private int countScopeNb(){
		int retValue = 0;
		
		for(int act=0; act<elementPozitionsInFile.length; act++){
			StringTokenizer tks = new StringTokenizer(fileContent[elementPozitionsInFile[act]]);
			tks.nextToken();
			tks.nextToken();
			String type = tks.nextToken();
			if(type.toLowerCase().contentEquals("scope"))
				retValue++;
		}
		
		return retValue;
	}
	
	private void initElementsArray(){
		elements = new Element[elementPozitionsInFile.length];
	}
	
	private void initWiresArray() throws Exception{
		int nbOfWires = countWireNb();
		if( nbOfWires < 1)
			throw new Exception("207");
		wires = new Wire[nbOfWires];
		saveWires = 0;
	}
	
	private int countWireNb(){
		int retValue = 0;
		
		for(int act=0; act<fileContent.length; act++){
			StringTokenizer tks = new StringTokenizer(fileContent[act]);
			String mark = tks.nextToken();
			if(mark.contentEquals("-"))
				retValue++;
		}
		
		return retValue;
	}
	
	//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*
	//fillElementsArray()
	
	private void fillElementsArray() throws Exception{
		for(int act=0; act<elementPozitionsInFile.length; act++)
			createElementFromLine(act);
	}
	
	private void createElementFromLine(int act) throws Exception{
		int typeOfElement = getTypeOfElement(act);
		createElementByType(typeOfElement, act);
	}
	
	//Display 0; And 1; Composite 2
	//Gate 3; Inverter 4; Or 5
	//SignalGenerator 6; Scope 7; Switch 8
	private int getTypeOfElement(int act) throws Exception{
		int retType = -1;
		StringTokenizer tks = new StringTokenizer(fileContent[ elementPozitionsInFile[act] ]);
		tks.nextToken(); tks.nextToken();
		String type = tks.nextToken();
		
		if(type.toLowerCase().contentEquals("display"))
			retType = 0;
		if(type.toLowerCase().contentEquals("and"))
			retType = 1;
		if(type.toLowerCase().contentEquals("composite"))
			retType = 2;
		if(type.toLowerCase().contentEquals("gate"))
			retType = 3;
		if(type.toLowerCase().contentEquals("inverter"))
			retType = 4;
		if(type.toLowerCase().contentEquals("or"))
			retType = 5;
		if(type.toLowerCase().contentEquals("signalgenerator"))
			retType = 6;
		if(type.toLowerCase().contentEquals("scope"))
			retType = 7;
		if(type.toLowerCase().contentEquals("switch"))
			retType = 8;
		
		else if(retType == -1)
			throw new Exception("208 "+fileContent[ elementPozitionsInFile[act] ]);
		
		return retType;
	}
	
	//Display 0; And 1; Composite 2
	//Gate 3; Inverter 4; Or 5
	//SignalGenerator 6; Scope 7; Switch 8
	private void createElementByType(int typeOfElement, int actPoz) throws Exception{
		try{
			switch(typeOfElement){
				case 0 : createDisplay(actPoz); return;
				case 1 : createAnd(actPoz); return;
				case 2 : createComposite(actPoz); return;
				case 3 : createGate(actPoz); return;
				case 4 : createInverter(actPoz); return;
				case 5 : createOr(actPoz); return;
				case 6 : createSignalGenerator(actPoz); return;
				case 7 : createScope(actPoz); return;
				case 8 : createSwitch(actPoz); return;
			}
		}catch(Exception e){
			throw new Exception(e.getMessage()+" atLine: "+fileContent[ elementPozitionsInFile[actPoz] ]);
		}
	}
	
	private void createDisplay(int actPoz) throws Exception{
		int[] numbers = getNumbersToCreateElementFromLine(actPoz);
		
		Display temp = new Display();
		temp.setInputWireNumbers( numbers[1] );
		temp.setOutputNumbers( numbers[2] );
		
		elements[ numbers[0] ] = temp;
		display[saveDisplayPozition] = temp;
		saveDisplayPozition++;
	}
	
	private void createAnd(int actPoz) throws Exception{
		int[] numbers = getNumbersToCreateElementFromLine(actPoz);
		
		AND temp = new AND();
		temp.setInputWireNumbers( numbers[1] );
		temp.setOutputNumbers( numbers[2]);
		for(int act=0; act<numbers[2]; act++){
			int nbOfWiresToActValue = countWireToActualValue(actPoz, act);
			temp.setOutputWireNumbers(act, nbOfWiresToActValue);
		}
		
		elements[ numbers[0] ] = temp;
	}
	
	private void createComposite(int actPoz) throws Exception{
		StringTokenizer tks = new StringTokenizer(fileContent[ elementPozitionsInFile[actPoz] ]);
		tks.nextToken();
		int elementsArrayPozition = getElementArrayPoz(tks.nextToken());
		tks.nextToken();
		String fileName = tks.nextToken();
		if(!tks.hasMoreTokens())
			throw new Exception("210 "+fileContent[ elementPozitionsInFile[actPoz] ]);
		int inputNumbers = getInputNumberFromString(tks.nextToken());
		if(!tks.hasMoreTokens())
			throw new Exception("211 "+fileContent[ elementPozitionsInFile[actPoz] ]);
		int outputNumbers = getOutputNumberFromString(tks.nextToken());
		
		ReadCircuitFromFile read = new ReadCircuitFromFile( nbOfCircuitElements+1 );
		CircuitElements copy = read.readInCircuit(fileName, nbOfMaxUpdates);
		
		Composite temp = new Composite(copy, nbOfMaxUpdates);
		temp.setInputWireNumbers(inputNumbers);
		temp.setOutputNumbers(outputNumbers);
		
		for(int act=0; act<outputNumbers; act++){
			int nbOfWiresToActValue = countWireToActualValue(actPoz, act);		
			temp.setOutputWireNumbers(act, nbOfWiresToActValue);
		}
		
		elements[ elementsArrayPozition ] = temp;
	
		composites[saveCompositePozition] = temp;
		saveCompositePozition++;
	}
	
	private void createGate(int actPoz) throws Exception{
		StringTokenizer tks = new StringTokenizer(fileContent[ elementPozitionsInFile[actPoz] ]);
		tks.nextToken();
		int elementsArrayPozition = getElementArrayPoz(tks.nextToken());
		tks.nextToken();
		String inputOrOutput = tks.nextToken();
		if(!tks.hasMoreTokens())
			throw new Exception("210 "+fileContent[ elementPozitionsInFile[actPoz] ]);
		int inputNumbers = getInputNumberFromString(tks.nextToken());
		if(!tks.hasMoreTokens())
			throw new Exception("211 "+fileContent[ elementPozitionsInFile[actPoz] ]);
		int outputNumbers = getOutputNumberFromString(tks.nextToken());
		
		Gate temp = new Gate();
		temp.setInputWireNumbers( inputNumbers );
		temp.setOutputNumbers( outputNumbers );
		if(inputOrOutput.toLowerCase().contentEquals("input"))
			for(int act=0; act<outputNumbers; act++){
				int nbOfWiresToActValue = countWireToActualValue(actPoz, act);
				temp.setOutputWireNumbers(act, nbOfWiresToActValue);
			}
		
		elements[ elementsArrayPozition ] = temp;
		
		if( inputOrOutput.toLowerCase().contentEquals("input") ){
			inputGate[saveInputGatePozition] = temp;
			saveInputGatePozition++;
		}
		if( inputOrOutput.toLowerCase().contentEquals("output") ){
			outputGate[saveOutputGatePozition] = temp;
			saveOutputGatePozition++;
		}
	}
	
	private void createInverter(int actPoz) throws Exception{
		int[] numbers = getNumbersToCreateElementFromLine(actPoz);
		
		Inverter temp = new Inverter();
		temp.setInputWireNumbers( numbers[1] );
		temp.setOutputNumbers(numbers[2] );
		for(int act=0; act<numbers[2]; act++){
			int nbOfWiresToActValue = countWireToActualValue(actPoz, act);
			temp.setOutputWireNumbers(act, nbOfWiresToActValue);
		}
		
		elements[ numbers[0] ] = temp;
	}
	
	private void createOr(int actPoz) throws Exception{
		int[] numbers = getNumbersToCreateElementFromLine(actPoz);
		
		OR temp = new OR();
		temp.setInputWireNumbers( numbers[1] );
		temp.setOutputNumbers( numbers[2] );
		for(int act=0; act<numbers[2]; act++){
			int nbOfWiresToActOutput = countWireToActualValue(actPoz, act);
			temp.setOutputWireNumbers(act, nbOfWiresToActOutput);
		}
		
		elements[ numbers[0] ] = temp;
	}
	
	private void createSignalGenerator(int actPoz) throws Exception{
		int[] numbers = getNumbersToCreateElementFromLine(actPoz);
		
		SignalGenerator temp = new SignalGenerator();
		temp.setInputWireNumbers( numbers[1] );
		temp.setOutputNumbers( numbers[2] );
		for(int act=0; act<numbers[2]; act++){
			int nbOfWiresToActOutput = countWireToActualValue(actPoz, act);
			temp.setOutputWireNumbers(act, nbOfWiresToActOutput);
		}
		
		elements[ numbers[0] ] = temp;
		signalGenerators[saveSignalGeneratorsPozition] = temp;
		saveSignalGeneratorsPozition++;
	}
	
	private void createScope(int actPoz) throws Exception{
		int[] numbers = getNumbersToCreateElementFromLine(actPoz);
		
		Scope temp = new Scope();
		temp.setInputWireNumbers( numbers[1] );
		temp.setOutputNumbers( numbers[2] );
		for(int act=0; act<numbers[2]; act++){
			int nbOfWiresToActOutput = countWireToActualValue(actPoz, act);
			temp.setOutputWireNumbers(act, nbOfWiresToActOutput);
		}
		
		elements[ numbers[0] ] = temp;		
		scope[saveScopePozition] = temp;
		saveScopePozition++;
	}
	
	private void createSwitch(int actPoz) throws Exception{		
		int[] numbers = getNumbersToCreateElementFromLine(actPoz);
		
		Switch temp = new Switch();
		temp.setInputWireNumbers( numbers[1] );
		
		temp.setOutputNumbers( numbers[2] );
		for(int act=0; act<numbers[2]; act++){
			int nbOfWiresToActOutput = countWireToActualValue(actPoz, act);
			temp.setOutputWireNumbers(act, nbOfWiresToActOutput);
		}
		
		elements[ numbers[0] ] = temp;
		switches[ saveSwitchesPozition ] = temp;
		saveSwitchesPozition++;
		
	}
	
	private int[] getNumbersToCreateElementFromLine(int actPoz) throws Exception{
		int[] retValue = new int[3];
		
		StringTokenizer tks = new StringTokenizer(fileContent[ elementPozitionsInFile[actPoz] ]);
		tks.nextToken();
		retValue[0] = getElementArrayPoz(tks.nextToken());
		tks.nextToken();
		if(!tks.hasMoreTokens())
			throw new Exception("210 "+fileContent[ elementPozitionsInFile[actPoz] ]);
		retValue[1] = getInputNumberFromString(tks.nextToken());
		if(!tks.hasMoreTokens())
			throw new Exception("211 "+fileContent[ elementPozitionsInFile[actPoz] ]);
		retValue[2] = getOutputNumberFromString(tks.nextToken());
		
		return retValue;
	}
	
	private int getElementArrayPoz( String num ) throws Exception{
		int retValue = -1;
		
		try{
			retValue = Integer.parseInt(num);
		}catch(Exception e){
			throw new Exception("204");
		}
		
		return retValue;
	}
	
	private int getInputNumberFromString( String num) throws Exception{
		int retValue = -1;
		
		try{
			retValue = Integer.parseInt(num);
		}catch(Exception e){
			throw new Exception("209");
		}
		
		return retValue;
	}
	
	private int getOutputNumberFromString( String num) throws Exception{
		int retValue = -1;
		
		try{
			retValue = Integer.parseInt(num);
		}catch(Exception e){
			throw new Exception("212");
		}
		
		return retValue;
	}
	
	private int countWireToActualValue(int actPoz, int value) throws Exception{
		int retValue = 0;
		
		for(int actLine=elementPozitionsInFile[actPoz]+1; actLine<fileContent.length; actLine++){
			StringTokenizer tks = new StringTokenizer(fileContent[actLine]);	
			
			if( !tks.nextToken().contentEquals("-") )
				break;
			int compareValue = getWireOutputNumberFromString( tks.nextToken() );
			if( compareValue == value )
				retValue++;
		}
		
		if(retValue  == 0)
			throw new Exception("220 "+fileContent[ elementPozitionsInFile[actPoz] ]);
		
		return retValue;
	}
	
	//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*
	//createWires()
	
	private void createWires() throws Exception{
		initWiresArray();
		fillWiresArray();
	}
	
	private void fillWiresArray() throws Exception{
		
		for(int actElement=0; actElement<elementPozitionsInFile.length; actElement++)
		try{
			fillWiresOfActualElement( actElement );
		}catch(Exception e){
			throw new Exception(e.getMessage()+" inLine of element="+fileContent[elementPozitionsInFile[actElement]]);
		}
	}
	
	private void fillWiresOfActualElement(int actElement) throws Exception{
		
		saveWiresOnActualElement = new int[elements[actElement].getOutputNumbers()];
		for(int act=0; act<saveWiresOnActualElement.length; act++)
			saveWiresOnActualElement[act] = 0;
		
		for(int actLine=elementPozitionsInFile[ actElement ]+1; actLine<fileContent.length; actLine++){
			StringTokenizer tks = new StringTokenizer(fileContent[actLine]);
			if( tks.nextToken().contentEquals("#") )
				break;

			try{
				fillWireFromLine(actElement,actLine);
			}catch(Exception e){
				throw new Exception(e.getMessage()+" inLine:"+fileContent[actLine]);
			}
		}
	}
	
	private void fillWireFromLine(int actElement, int actLine) throws Exception{
		int[] numbers = getNumbersToCreateWire(actLine);
		
		Wire temp = new Wire();
		Composite reference = new Composite(null, 0);
		
		if( elements[actElement].getClass().equals(reference.getClass()) ){
			Composite use = (Composite)elements[actElement];
			temp.setInputElement( use.getActualOutputGate( numbers[0] ) );
			temp.setNbOfOutputOnInputElement(numbers[0]);
		}
		else{
			temp.setInputElement(elements[actElement]);
			temp.setNbOfOutputOnInputElement(numbers[0]);
		}
		
		if( elements[numbers[1]].getClass().equals(reference.getClass()) ){
			Composite use = (Composite)elements[numbers[1]];
			temp.setOutputElement( use.getActualInputGate( numbers[2] ) );
		}
		else
			temp.setOutputElement(elements[numbers[1]]);
		
		elements[actElement].setActualOutputWire(numbers[0], saveWiresOnActualElement[ numbers[0] ], temp);
		saveWiresOnActualElement[ numbers[0] ]++;

		elements[numbers[1]].setActualInputWire(numbers[2], temp);
		
		wires[saveWires] = temp;
		wires[saveWires].setNbOfOutputOnInputElement(numbers[2]);
		saveWires++;
	}
	
	private int[] getNumbersToCreateWire(int actLine) throws Exception{
		int[] retValue = new int[3];
		StringTokenizer tks = new StringTokenizer(fileContent[actLine]);
		
		tks.nextToken();
		if(!tks.hasMoreTokens())
			throw new Exception("214 "+fileContent[actLine]);
		retValue[0] = getWireOutputNumberFromString(tks.nextToken());
		if(!tks.hasMoreTokens())
			throw new Exception("215 "+fileContent[actLine]);
		retValue[1] = getWireInputElementNumberFromString(tks.nextToken());
		if(!tks.hasMoreTokens())
			throw new Exception("218 "+fileContent[actLine]);
		retValue[2] = getWireInputElementActualNumberFromString(tks.nextToken());
		
		return retValue;
	}
	
	private int getWireOutputNumberFromString( String num) throws Exception{
		int retValue = -1;
		
		try{
			retValue = Integer.parseInt(num);
		}catch(Exception e){
			throw new Exception("213");
		}
		
		return retValue;
	}
	
	private int getWireInputElementNumberFromString( String num) throws Exception{
		int retValue = -1;
		
		try{
			retValue = Integer.parseInt(num);
		}catch(Exception e){
			throw new Exception("216");
		}
		if( (retValue < 0) || (elementPozitionsInFile.length <= retValue) )
			throw new Exception("217");
		
		return retValue;
	}
	
	private int getWireInputElementActualNumberFromString( String num) throws Exception{
		int retValue = -1;
		
		try{
			retValue = Integer.parseInt(num);
		}catch(Exception e){
			throw new Exception("219");
		}
		
		return retValue;
	}
	
}
